पाइथन के 'email' पैकेज को अनलॉक करें। प्रभावी और वैश्विक रूप से डेटा निकालने के लिए जटिल MIME संदेश बनाना और आने वाले ईमेल को पार्स करना सीखें।
पाइथन के ईमेल पैकेज में महारत: MIME संदेश निर्माण और मजबूत पार्सिंग की कला
ईमेल वैश्विक संचार का एक आधार स्तंभ बना हुआ है, जो व्यक्तिगत पत्राचार, व्यावसायिक संचालन और स्वचालित सिस्टम सूचनाओं के लिए अपरिहार्य है। हर रिच-टेक्स्ट ईमेल, हर अटैचमेंट, और हर सावधानीपूर्वक स्वरूपित हस्ताक्षर के पीछे मल्टीपर्पस इंटरनेट मेल एक्सटेंशन्स (MIME) की जटिलता छिपी होती है। डेवलपर्स के लिए, विशेष रूप से पाइथन के साथ काम करने वालों के लिए, प्रोग्रामेटिक रूप से इन MIME संदेशों का निर्माण और पार्स करना एक महत्वपूर्ण कौशल है।
पाइथन का अंतर्निहित email
पैकेज ईमेल संदेशों को संभालने के लिए एक मजबूत और व्यापक ढाँचा प्रदान करता है। यह केवल साधारण टेक्स्ट भेजने के लिए नहीं है; इसे MIME के जटिल विवरणों को दूर करने के लिए डिज़ाइन किया गया है, जिससे आप परिष्कृत ईमेल बना सकते हैं और आने वाले ईमेल से विशिष्ट डेटा को उल्लेखनीय सटीकता के साथ निकाल सकते हैं। यह गाइड आपको इस पैकेज के दो प्राथमिक पहलुओं में गहराई से ले जाएगा: भेजने के लिए MIME संदेशों का निर्माण और डेटा निकालने के लिए उन्हें पार्स करना, सर्वोत्तम प्रथाओं पर एक वैश्विक दृष्टिकोण प्रदान करना।
निर्माण और पार्सिंग दोनों को समझना महत्वपूर्ण है। जब आप एक संदेश का निर्माण करते हैं, तो आप अनिवार्य रूप से किसी अन्य सिस्टम द्वारा व्याख्या किए जाने के लिए इसकी संरचना और सामग्री को परिभाषित कर रहे होते हैं। जब आप पार्स करते हैं, तो आप किसी अन्य सिस्टम द्वारा परिभाषित संरचना और सामग्री की व्याख्या कर रहे होते हैं। एक की गहरी समझ दूसरे में महारत हासिल करने में बहुत मदद करती है, जिससे अधिक लचीले और इंटरऑपरेबल ईमेल एप्लिकेशन बनते हैं।
MIME को समझना: आधुनिक ईमेल की रीढ़
पाइथन की बारीकियों में गोता लगाने से पहले, यह समझना आवश्यक है कि MIME क्या है और यह इतना महत्वपूर्ण क्यों है। मूल रूप से, ईमेल संदेश केवल सादे पाठ (7-बिट ASCII अक्षर) तक ही सीमित थे। 1990 के दशक की शुरुआत में पेश किए गए MIME ने ईमेल की क्षमताओं का विस्तार किया ताकि यह समर्थन कर सके:
- गैर-ASCII वर्ण: अरबी, चीनी, रूसी, या किसी भी अन्य भाषा में पाठ की अनुमति देना जो ASCII सेट के बाहर के वर्णों का उपयोग करती है।
- अटैचमेंट: दस्तावेज़, चित्र, ऑडियो और वीडियो जैसी फ़ाइलें भेजना।
- रिच टेक्स्ट फ़ॉर्मेटिंग: बोल्डिंग, इटैलिक, रंग और लेआउट वाले HTML ईमेल।
- एकाधिक भाग: एक ही ईमेल के भीतर सादे पाठ, HTML और अटैचमेंट को मिलाना।
MIME इसे ईमेल संदेश में विशिष्ट हेडर जोड़कर और इसके बॉडी को विभिन्न "भागों" में संरचित करके प्राप्त करता है। आपके सामने आने वाले प्रमुख MIME हेडर में शामिल हैं:
Content-Type:
किसी भाग में डेटा के प्रकार को निर्दिष्ट करता है (जैसे,text/plain
,text/html
,image/jpeg
,application/pdf
,multipart/alternative
)। इसमें अक्सर एकcharset
पैरामीटर भी शामिल होता है (जैसे,charset=utf-8
)।Content-Transfer-Encoding:
यह इंगित करता है कि ईमेल क्लाइंट को सामग्री को कैसे डीकोड करना चाहिए (जैसे, बाइनरी डेटा के लिएbase64
, ज्यादातर टेक्स्ट के लिएquoted-printable
जिसमें कुछ गैर-ASCII वर्ण हों)।Content-Disposition:
यह सुझाव देता है कि प्राप्तकर्ता का ईमेल क्लाइंट भाग को कैसे प्रदर्शित करे (जैसे, संदेश के मुख्य भाग में प्रदर्शन के लिएinline
, सहेजने के लिए फ़ाइल के लिएattachment
)।
पाइथन email
पैकेज: एक गहरा गोता
पाइथन का email
पैकेज एक व्यापक लाइब्रेरी है जिसे प्रोग्रामेटिक रूप से ईमेल संदेश बनाने, पार्स करने और संशोधित करने के लिए डिज़ाइन किया गया है। यह Message
ऑब्जेक्ट्स की अवधारणा के आसपास बनाया गया है, जो एक ईमेल की संरचना का प्रतिनिधित्व करते हैं।
पैकेज के भीतर प्रमुख मॉड्यूल में शामिल हैं:
email.message:
इसमें कोरEmailMessage
क्लास होती है, जो ईमेल संदेश बनाने और उनमें हेरफेर करने के लिए प्राथमिक इंटरफ़ेस है। यह एक अत्यधिक लचीली क्लास है जो MIME विवरणों को स्वचालित रूप से संभालती है।email.mime:
लिगेसी क्लासेस (जैसेMIMEText
,MIMEMultipart
) प्रदान करता है जो MIME संरचना पर अधिक स्पष्ट नियंत्रण प्रदान करते हैं। जबकिEmailMessage
को इसकी सादगी के कारण आमतौर पर नए कोड के लिए पसंद किया जाता है, इन क्लासों को समझना फायदेमंद हो सकता है।email.parser:
रॉ ईमेल डेटा (बाइट्स या स्ट्रिंग्स) कोEmailMessage
ऑब्जेक्ट्स में बदलने के लिएBytesParser
औरParser
जैसी क्लासेस प्रदान करता है।email.policy:
नीतियां परिभाषित करता है जो यह नियंत्रित करती हैं कि ईमेल संदेश कैसे बनाए और पार्स किए जाते हैं, जो हेडर एन्कोडिंग, लाइन एंडिंग्स और त्रुटि हैंडलिंग को प्रभावित करते हैं।
अधिकांश आधुनिक उपयोग के मामलों के लिए, आप मुख्य रूप से निर्माण और पार्स किए गए संदेश ऑब्जेक्ट दोनों के लिए email.message.EmailMessage
क्लास के साथ इंटरैक्ट करेंगे। इसके तरीके उस प्रक्रिया को बहुत सरल बनाते हैं जो पहले लिगेसी email.mime
क्लासों के साथ अधिक विस्तृत थी।
MIME संदेश निर्माण: सटीकता के साथ ईमेल बनाना
ईमेल बनाने में विभिन्न घटकों (टेक्स्ट, HTML, अटैचमेंट) को एक वैध MIME संरचना में इकट्ठा करना शामिल है। EmailMessage
क्लास इस प्रक्रिया को महत्वपूर्ण रूप से सुव्यवस्थित करती है।
बुनियादी टेक्स्ट ईमेल
सबसे सरल ईमेल सादा टेक्स्ट होता है। आप एक बना सकते हैं और बुनियादी हेडर आसानी से सेट कर सकते हैं:
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = 'Greetings from Python'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg.set_content('Hello, this is a plain text email sent from Python.\n\nBest regards,\nYour Python Script')
print(msg.as_string())
स्पष्टीकरण:
EmailMessage()
एक खाली संदेश ऑब्जेक्ट बनाता है।- शब्दकोश-जैसी पहुँच (
msg['Subject'] = ...
) सामान्य हेडर सेट करती है। set_content()
ईमेल की प्राथमिक सामग्री जोड़ता है। डिफ़ॉल्ट रूप से, यहContent-Type: text/plain; charset="utf-8"
का अनुमान लगाता है।as_string()
संदेश को एक स्ट्रिंग प्रारूप में सीरियलाइज करता है जो SMTP के माध्यम से भेजने या फ़ाइल में सहेजने के लिए उपयुक्त है।
HTML सामग्री जोड़ना
HTML ईमेल भेजने के लिए, आप बस set_content()
को कॉल करते समय सामग्री प्रकार निर्दिष्ट करते हैं। उन प्राप्तकर्ताओं के लिए एक सादा टेक्स्ट विकल्प प्रदान करना एक अच्छी प्रथा है जिनके ईमेल क्लाइंट HTML प्रस्तुत नहीं करते हैं, या पहुंच कारणों से।
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = 'Your HTML Newsletter'
msg['From'] = 'newsletter@example.com'
msg['To'] = 'subscriber@example.com'
html_content = """
<html>
<head></head>
<body>
<h1>Welcome to Our Global Update!</h1>
<p>Dear Subscriber,</p>
<p>This is your <strong>latest update</strong> from around the world.</p>
<p>Visit our <a href="http://www.example.com">website</a> for more.</p>
<p>Best regards,<br>The Team</p>
</body>
</html>
"""
# Add the HTML version
msg.add_alternative(html_content, subtype='html')
# Add a plain text fallback
plain_text_content = (
"Welcome to Our Global Update!\n\n"
"Dear Subscriber,\n\n"
"This is your latest update from around the world.\n"
"Visit our website for more: http://www.example.com\n\n"
"Best regards,\nThe Team"
)
msg.add_alternative(plain_text_content, subtype='plain')
print(msg.as_string())
स्पष्टीकरण:
add_alternative()
का उपयोग *एक ही* सामग्री के विभिन्न प्रस्तुतियों को जोड़ने के लिए किया जाता है। ईमेल क्लाइंट "सबसे अच्छा" वाला प्रदर्शित करेगा जिसे वह संभाल सकता है (आमतौर पर HTML)।- यह स्वचालित रूप से एक
multipart/alternative
MIME संरचना बनाता है।
अटैचमेंट संभालना
add_attachment()
का उपयोग करके फ़ाइलें संलग्न करना सीधा है। आप किसी भी प्रकार की फ़ाइल संलग्न कर सकते हैं, और पैकेज उपयुक्त MIME प्रकारों और एन्कोडिंग (आमतौर पर base64
) को संभालता है।
from email.message import EmailMessage
from pathlib import Path
# Create dummy files for demonstration
Path('report.pdf').write_bytes(b'%PDF-1.4\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n2 0 obj<</Count 0>>endobj\nxref\n0 3\n0000000000 65535 f\n0000000009 00000 n\n0000000052 00000 n\ntrailer<</Size 3/Root 1 0 R>>startxref\n104\n%%EOF') # A very basic, invalid PDF placeholder
Path('logo.png').write_bytes(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0cIDAT\x08\x99c`\x00\x00\x00\x02\x00\x01\xe2!\x00\xa0\x00\x00\x00\x00IEND\xaeB`\x82') # A 1x1 transparent PNG placeholder
msg = EmailMessage()
msg['Subject'] = 'Important Document and Image'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg.set_content('Please find the attached report and company logo.')
# Attach a PDF file
with open('report.pdf', 'rb') as f:
file_data = f.read()
msg.add_attachment(
file_data,
maintype='application',
subtype='pdf',
filename='Annual_Report_2024.pdf'
)
# Attach an image file
with open('logo.png', 'rb') as f:
image_data = f.read()
msg.add_attachment(
image_data,
maintype='image',
subtype='png',
filename='CompanyLogo.png'
)
print(msg.as_string())
# Clean up dummy files
Path('report.pdf').unlink()
Path('logo.png').unlink()
स्पष्टीकरण:
add_attachment()
फ़ाइल सामग्री के रॉ बाइट्स लेता है।maintype
औरsubtype
MIME प्रकार निर्दिष्ट करते हैं (जैसे,application/pdf
,image/png
)। ये प्राप्तकर्ता के ईमेल क्लाइंट के लिए अटैचमेंट को सही ढंग से पहचानने और संभालने के लिए महत्वपूर्ण हैं।filename
वह नाम प्रदान करता है जिसके तहत अटैचमेंट प्राप्तकर्ता द्वारा सहेजा जाएगा।- यह स्वचालित रूप से एक
multipart/mixed
संरचना स्थापित करता है।
मल्टीपार्ट संदेश बनाना
जब आपके पास HTML बॉडी, एक सादा टेक्स्ट फ़ॉलबैक, और इनलाइन छवियों या संबंधित फ़ाइलों वाला संदेश होता है, तो आपको एक अधिक जटिल मल्टीपार्ट संरचना की आवश्यकता होती है। EmailMessage
क्लास इसे add_related()
और add_alternative()
के साथ बुद्धिमानी से संभालती है।
एक सामान्य परिदृश्य HTML में सीधे एम्बेडेड एक छवि वाला HTML ईमेल है (एक "इनलाइन" छवि)। यह multipart/related
का उपयोग करता है।
from email.message import EmailMessage
from pathlib import Path
# Create a dummy image file for demonstration (a 1x1 transparent PNG)
Path('banner.png').write_bytes(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0cIDAT\x08\x99c`\x00\x00\x00\x02\x00\x01\xe2!\x00\xa0\x00\x00\x00\x00IEND\xaeB`\x82')
msg = EmailMessage()
msg['Subject'] = 'Inline Image Example'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
# Plain text version (fallback)
plain_text = 'Check out our amazing banner!\n\n[Image: Banner.png]\n\nVisit our site.'
msg.set_content(plain_text, subtype='plain') # Set initial plain text content
# HTML version (with CID for inline image)
html_content = """
<html>
<head></head>
<body>
<h1>Our Latest Offer!</h1>
<p>Dear Customer,</p>
<p>Don't miss out on our special global promotion:</p>
<img src="cid:my-banner-image" alt="Promotion Banner">
<p>Click <a href="http://www.example.com">here</a> to learn more.</p>
</body>
</html>
"""
msg.add_alternative(html_content, subtype='html') # Add HTML alternative
# Add the inline image (related content)
with open('banner.png', 'rb') as img_file:
image_data = img_file.read()
msg.add_related(
image_data,
maintype='image',
subtype='png',
cid='my-banner-image' # This CID matches the 'src' in HTML
)
print(msg.as_string())
# Clean up dummy file
Path('banner.png').unlink()
स्पष्टीकरण:
set_content()
प्रारंभिक सामग्री (यहाँ, सादा टेक्स्ट) स्थापित करता है।add_alternative()
HTML संस्करण जोड़ता है, जिससे एकmultipart/alternative
संरचना बनती है जिसमें सादा टेक्स्ट और HTML भाग होते हैं।add_related()
का उपयोग उस सामग्री के लिए किया जाता है जो संदेश के किसी एक भाग से "संबंधित" है, आमतौर पर HTML में इनलाइन छवियां। यह एकcid
(Content-ID) पैरामीटर लेता है, जिसे फिर HTML<img src="cid:my-banner-image">
टैग में संदर्भित किया जाता है।- अंतिम संरचना
multipart/mixed
(यदि बाहरी अटैचमेंट थे) होगी जिसमें एकmultipart/alternative
भाग होगा, जिसमें बदले में एकmultipart/related
भाग होगा।multipart/related
भाग में HTML और इनलाइन छवि होती है।EmailMessage
क्लास आपके लिए इस नेस्टिंग जटिलता को संभालती है।
वैश्विक पहुंच के लिए एन्कोडिंग और कैरेक्टर सेट
अंतर्राष्ट्रीय संचार के लिए, उचित कैरेक्टर एन्कोडिंग सर्वोपरि है। email
पैकेज, डिफ़ॉल्ट रूप से, UTF-8 का उपयोग करने के बारे में अत्यधिक राय रखता है, जो दुनिया भर से विविध कैरेक्टर सेट को संभालने के लिए सार्वभौमिक मानक है।
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = 'Global Characters: こんにちは, Привет, नमस्ते'
msg['From'] = 'global_sender@example.com'
msg['To'] = 'global_recipient@example.com'
# Japanese, Russian, and Hindi characters
content = "This message contains diverse global characters:\n"
content += "こんにちは (Japanese)\n"
content += "Привет (Russian)\n"
content += "नमस्ते (Hindi)\n\n"
content += "The 'email' package handles UTF-8 gracefully."
msg.set_content(content)
print(msg.as_string())
स्पष्टीकरण:
- जब
set_content()
को एक पाइथन स्ट्रिंग प्राप्त होती है, तो यह स्वचालित रूप से इसे UTF-8 में एन्कोड करता है औरContent-Type: text/plain; charset="utf-8"
हेडर सेट करता है। - यदि सामग्री को इसकी आवश्यकता होती है (उदाहरण के लिए, इसमें कई गैर-ASCII वर्ण होते हैं), तो यह पुराने ईमेल सिस्टम पर सुरक्षित प्रसारण सुनिश्चित करने के लिए
Content-Transfer-Encoding: quoted-printable
याbase64
भी लागू कर सकता है। पैकेज चुनी गई नीति के अनुसार इसे स्वचालित रूप से संभालता है।
कस्टम हेडर और नीतियां
आप किसी ईमेल में कोई भी कस्टम हेडर जोड़ सकते हैं। नीतियां (email.policy
से) परिभाषित करती हैं कि संदेशों को कैसे संभाला जाता है, जो हेडर एन्कोडिंग, लाइन एंडिंग्स और त्रुटि हैंडलिंग जैसे पहलुओं को प्रभावित करती हैं। डिफ़ॉल्ट नीति आम तौर पर अच्छी होती है, लेकिन आप सख्त SMTP अनुपालन के लिए `SMTP` चुन सकते हैं या कस्टम नीतियां परिभाषित कर सकते हैं।
from email.message import EmailMessage
from email import policy
msg = EmailMessage(policy=policy.SMTP)
msg['Subject'] = 'Email with Custom Header'
msg['From'] = 'info@example.org'
msg['To'] = 'user@example.org'
msg['X-Custom-Header'] = 'This is a custom value for tracking'
msg['Reply-To'] = 'support@example.org'
msg.set_content('This email demonstrates custom headers and policies.')
print(msg.as_string())
स्पष्टीकरण:
policy=policy.SMTP
का उपयोग SMTP मानकों के साथ सख्त अनुपालन सुनिश्चित करता है, जो वितरण क्षमता के लिए महत्वपूर्ण हो सकता है।- कस्टम हेडर मानक हेडर की तरह ही जोड़े जाते हैं। वे अक्सर गैर-मानक हेडर को दर्शाने के लिए
X-
से शुरू होते हैं।
MIME संदेश पार्सिंग: आने वाले ईमेल से जानकारी निकालना
पार्सिंग में रॉ ईमेल डेटा (आमतौर पर IMAP के माध्यम से या किसी फ़ाइल से प्राप्त) लेना और उसे एक `EmailMessage` ऑब्जेक्ट में बदलना शामिल है जिसे आप फिर आसानी से जांच और हेरफेर कर सकते हैं।
लोडिंग और प्रारंभिक पार्सिंग
आप आमतौर पर ईमेल को रॉ बाइट्स के रूप में प्राप्त करेंगे। इसके लिए email.parser.BytesParser
(या सुविधा फ़ंक्शन email.message_from_bytes()
) का उपयोग किया जाता है।
from email.parser import BytesParser
from email.policy import default
raw_email_bytes = b"""
From: sender@example.com
To: recipient@example.com
Subject: Test Email with Basic Headers
Date: Mon, 1 Jan 2024 10:00:00 +0000
Content-Type: text/plain; charset="utf-8"
This is the body of the email.
It's a simple test.
"""
# Using BytesParser
parser = BytesParser(policy=default)
msg = parser.parsebytes(raw_email_bytes)
# Or using the convenience function
# from email import message_from_bytes
# msg = message_from_bytes(raw_email_bytes, policy=default)
print(f"Subject: {msg['subject']}")
print(f"From: {msg['from']}")
print(f"Content-Type: {msg['Content-Type']}")
स्पष्टीकरण:
BytesParser
रॉ बाइट डेटा लेता है (जिस तरह से ईमेल प्रसारित होते हैं) और एकEmailMessage
ऑब्जेक्ट लौटाता है।policy=default
पार्सिंग नियमों को निर्दिष्ट करता है।
हेडर तक पहुँचना
हेडर शब्दकोश-जैसी कीज़ के माध्यम से आसानी से सुलभ हैं। पैकेज स्वचालित रूप से एन्कोडेड हेडर (जैसे, अंतर्राष्ट्रीय वर्णों वाले विषय) की डिकोडिंग को संभालता है।
# ... (using the 'msg' object from the previous parsing example)
print(f"Date: {msg['date']}")
print(f"Message ID: {msg['Message-ID'] if 'Message-ID' in msg else 'N/A'}")
# Handling multiple headers (e.g., 'Received' headers)
# from email.message import EmailMessage # If not imported yet
# from email import message_from_string # For a quick string example
multi_header_email = message_from_string(
"""
From: a@example.com
To: b@example.com
Subject: Multi-header Test
Received: from client.example.com (client.example.com [192.168.1.100])
by server.example.com (Postfix) with ESMTP id 123456789
for <b@example.com>; Mon, 1 Jan 2024 10:00:00 +0000 (GMT)
Received: from mx.another.com (mx.another.com [192.168.1.101])
by server.example.com (Postfix) with ESMTP id 987654321
for <b@example.com>; Mon, 1 Jan 2024 09:59:00 +0000 (GMT)
Body content here.
"""
)
received_headers = multi_header_email.get_all('received')
if received_headers:
print("\nReceived Headers:")
for header in received_headers:
print(f"- {header}")
स्पष्टीकरण:
- किसी हेडर तक पहुँचने से उसका मान एक स्ट्रिंग के रूप में प्राप्त होता है।
get_all('header-name')
उन हेडरों के लिए उपयोगी है जो कई बार दिखाई दे सकते हैं (जैसेReceived
)।- पैकेज हेडर डिकोडिंग को संभालता है, इसलिए
Subject: =?utf-8?Q?Global_Characters:_=E3=81=93=E3=82=93=E3=81=AB=E3=81=A1=E3=81=AF?=
जैसे मान स्वचालित रूप से पठनीय स्ट्रिंग्स में परिवर्तित हो जाते हैं।
बॉडी कंटेंट निकालना
वास्तविक संदेश बॉडी निकालने के लिए यह जांचना आवश्यक है कि संदेश मल्टीपार्ट है या नहीं। मल्टीपार्ट संदेशों के लिए, आप इसके भागों के माध्यम से पुनरावृति करते हैं।
from email.message import EmailMessage
from email import message_from_string
multipart_email_raw = """
From: multi@example.com
To: user@example.com
Subject: Test Multipart Email
Content-Type: multipart/alternative; boundary="_----------=_12345"
--_----------=_12345
Content-Type: text/plain; charset="utf-8"
Hello from the plain text part!
--_----------=_12345
Content-Type: text/html; charset="utf-8"
<html>
<body>
<h1>Hello from the HTML part!</h1>
<p>This is a <strong>rich text</strong> email.</p>
</body>
</html>
--_----------=_12345--
"""
msg = message_from_string(multipart_email_raw)
if msg.is_multipart():
print("\n--- Multipart Email Body ---")
for part in msg.iter_parts():
content_type = part.get_content_type()
charset = part.get_content_charset() or 'utf-8' # Default to utf-8 if not specified
payload = part.get_payload(decode=True) # Decode payload bytes
try:
decoded_content = payload.decode(charset)
print(f"Content-Type: {content_type}, Charset: {charset}\nContent:\n{decoded_content}\n")
except UnicodeDecodeError:
print(f"Content-Type: {content_type}, Charset: {charset}\nContent: (Binary or undecodable data)\n")
# Handle binary data, or attempt a fallback encoding
else:
print("\n--- Single Part Email Body ---")
charset = msg.get_content_charset() or 'utf-8'
payload = msg.get_payload(decode=True)
try:
decoded_content = payload.decode(charset)
print(f"Content-Type: {msg.get_content_type()}, Charset: {charset}\nContent:\n{decoded_content}\n")
except UnicodeDecodeError:
print(f"Content: (Binary or undecodable data)\n")
स्पष्टीकरण:
is_multipart()
यह निर्धारित करता है कि ईमेल में कई भाग हैं या नहीं।iter_parts()
एक मल्टीपार्ट संदेश के सभी उप-भागों के माध्यम से पुनरावृति करता है।get_content_type()
पूरा MIME प्रकार लौटाता है (जैसे,text/plain
)।get_content_charset()
Content-Type
हेडर से कैरेक्टर सेट निकालता है।get_payload(decode=True)
महत्वपूर्ण है: यह *डीकोडेड* सामग्री को बाइट्स के रूप में लौटाता है। फिर आपको पाइथन स्ट्रिंग प्राप्त करने के लिए इन बाइट्स को सही कैरेक्टर सेट का उपयोग करके.decode()
करना होगा।
पार्सिंग के दौरान अटैचमेंट संभालना
अटैचमेंट भी एक मल्टीपार्ट संदेश के भाग होते हैं। आप उन्हें उनके Content-Disposition
हेडर का उपयोग करके पहचान सकते हैं और उनके डीकोडेड पेलोड को सहेज सकते हैं।
from email.message import EmailMessage
from email import message_from_string
import os
# Example email with a simple attachment
email_with_attachment = """
From: attach@example.com
To: user@example.com
Subject: Document Attached
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="_----------=_XYZ"
--_----------=_XYZ
Content-Type: text/plain; charset="utf-8"
Here is your requested document.
--_----------=_XYZ
Content-Type: application/pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="document.pdf"
JVBERi0xLjQKMSAwIG9iagpbL1BERi9UZXh0L0ltYWdlQy9JbWFnZUkvSW1hZ0VCXQplbmRvYmoK
--_----------=_XYZ--
"""
msg = message_from_string(email_with_attachment)
output_dir = 'parsed_attachments'
os.makedirs(output_dir, exist_ok=True)
print("\n--- Processing Attachments ---")
for part in msg.iter_attachments():
filename = part.get_filename()
if filename:
filepath = os.path.join(output_dir, filename)
try:
with open(filepath, 'wb') as f:
f.write(part.get_payload(decode=True))
print(f"Saved attachment: {filepath} (Type: {part.get_content_type()})")
except Exception as e:
print(f"Error saving {filename}: {e}")
else:
print(f"Found an attachment without a filename (Content-Type: {part.get_content_type()})")
# Clean up the output directory
# import shutil
# shutil.rmtree(output_dir)
स्पष्टीकरण:
iter_attachments()
विशेष रूप से उन भागों को उत्पन्न करता है जो संभावित रूप से अटैचमेंट हैं (अर्थात, जिनके पासContent-Disposition: attachment
हेडर है या अन्यथा वर्गीकृत नहीं हैं)।get_filename()
Content-Disposition
हेडर से फ़ाइल नाम निकालता है।part.get_payload(decode=True)
अटैचमेंट की रॉ बाइनरी सामग्री को पुनः प्राप्त करता है, जो पहले से हीbase64
याquoted-printable
से डीकोड की गई है।
एन्कोडिंग और कैरेक्टर सेट को डीकोड करना
जब आप get_payload(decode=True)
को कॉल करते हैं तो email
पैकेज सामान्य ट्रांसफर एन्कोडिंग (जैसे base64
, quoted-printable
) को स्वचालित रूप से डीकोड करने का एक उत्कृष्ट काम करता है। टेक्स्ट सामग्री के लिए, यह Content-Type
हेडर में निर्दिष्ट charset
का उपयोग करने का प्रयास करता है। यदि कोई कैरेक्टर सेट निर्दिष्ट नहीं है या यह अमान्य है, तो आपको इसे शालीनता से संभालने की आवश्यकता हो सकती है।
from email.message import EmailMessage
from email import message_from_string
# Example with a potentially problematic charset
email_latin1 = """
From: legacy@example.com
To: new_system@example.com
Subject: Special characters: àéíóú
Content-Type: text/plain; charset="iso-8859-1"
This message contains Latin-1 characters: àéíóú
"""
msg = message_from_string(email_latin1)
if msg.is_multipart():
for part in msg.iter_parts():
payload = part.get_payload(decode=True)
charset = part.get_content_charset() or 'utf-8'
try:
print(f"Decoded (Charset: {charset}): {payload.decode(charset)}")
except UnicodeDecodeError:
print(f"Failed to decode with {charset}. Trying fallback...")
# Fallback to a common charset or 'latin-1' if expecting it
print(f"Decoded (Fallback Latin-1): {payload.decode('latin-1', errors='replace')}")
else:
payload = msg.get_payload(decode=True)
charset = msg.get_content_charset() or 'utf-8'
try:
print(f"Decoded (Charset: {charset}): {payload.decode(charset)}")
except UnicodeDecodeError:
print(f"Failed to decode with {charset}. Trying fallback...")
print(f"Decoded (Fallback Latin-1): {payload.decode('latin-1', errors='replace')}")
स्पष्टीकरण:
- हमेशा
Content-Type
हेडर में निर्दिष्ट कैरेक्टर सेट का उपयोग करने का प्रयास करें। - मजबूती के लिए
try-except UnicodeDecodeError
ब्लॉक का उपयोग करें, खासकर जब विविध और संभावित रूप से गैर-मानक स्रोतों से ईमेल के साथ काम कर रहे हों। .decode()
के साथerrors='replace'
याerrors='ignore'
का उपयोग उन वर्णों को संभालने के लिए किया जा सकता है जिन्हें लक्ष्य एन्कोडिंग में मैप नहीं किया जा सकता है, जिससे क्रैश को रोका जा सकता है।
उन्नत पार्सिंग परिदृश्य
वास्तविक दुनिया के ईमेल अत्यधिक जटिल हो सकते हैं, जिनमें नेस्टेड मल्टीपार्ट संरचनाएं होती हैं। email
पैकेज की पुनरावर्ती प्रकृति इन नेविगेट करना सीधा बनाती है। आप गहरे नेस्टेड संदेशों को पार करने के लिए is_multipart()
को iter_parts()
के साथ जोड़ सकते हैं।
from email.message import EmailMessage
from email import message_from_string
def parse_email_part(part, indent=0):
prefix = " " * indent
content_type = part.get_content_type()
charset = part.get_content_charset() or 'N/A'
print(f"{prefix}Part Type: {content_type}, Charset: {charset}")
if part.is_multipart():
for subpart in part.iter_parts():
parse_email_part(subpart, indent + 1)
elif part.get_filename(): # It's an attachment
print(f"{prefix} Attachment: {part.get_filename()} (Size: {len(part.get_payload(decode=True))} bytes)")
else: # It's a regular text/html body part
payload = part.get_payload(decode=True)
try:
decoded_content = payload.decode(charset)
# print(f"{prefix} Content (first 100 chars): {decoded_content[:100]}...") # For brevity
except UnicodeDecodeError:
print(f"{prefix} Content: (Binary or undecodable text)")
complex_email_raw = """
From: complex@example.com
To: receiver@example.com
Subject: Complex Email with HTML, Plain, and Attachment
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="outer_boundary"
--outer_boundary
Content-Type: multipart/alternative; boundary="inner_boundary"
--inner_boundary
Content-Type: text/plain; charset="utf-8"
Plain text content.
--inner_boundary
Content-Type: text/html; charset="utf-8"
<html><body><h2>HTML Content</h2></body></html>
--inner_boundary--
--outer_boundary
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="data.bin"
SGVsbG8gV29ybGQh
--outer_boundary--
"""
msg = message_from_string(complex_email_raw)
print("\n--- Traversing Complex Email Structure ---")
parse_email_part(msg)
स्पष्टीकरण:
- पुनरावर्ती फ़ंक्शन
parse_email_part
यह दर्शाता है कि पूरे संदेश ट्री के माध्यम से कैसे चलना है, प्रत्येक स्तर पर मल्टीपार्ट भागों, अटैचमेंट और बॉडी सामग्री की पहचान करना। - यह पैटर्न गहरे नेस्टेड ईमेल से विशिष्ट प्रकार की सामग्री निकालने के लिए अत्यधिक लचीला है।
निर्माण बनाम पार्सिंग: एक तुलनात्मक परिप्रेक्ष्य
यद्यपि अलग-अलग संचालन, निर्माण और पार्सिंग एक ही सिक्के के दो पहलू हैं: MIME संदेश हैंडलिंग। एक को समझना अनिवार्य रूप से दूसरे की सहायता करता है।
निर्माण (भेजना):
- फोकस: हेडर, सामग्री और अटैचमेंट को एक मानक-अनुपालन MIME संरचना में सही ढंग से इकट्ठा करना।
- प्राथमिक उपकरण:
email.message.EmailMessage
जिसमेंset_content()
,add_attachment()
,add_alternative()
,add_related()
जैसे तरीके हैं। - मुख्य चुनौतियाँ: सही MIME प्रकार, कैरेक्टर सेट (विशेष रूप से वैश्विक समर्थन के लिए UTF-8), `Content-Transfer-Encoding`, और उचित हेडर स्वरूपण सुनिश्चित करना। गलतियाँ ईमेल को सही ढंग से प्रदर्शित नहीं होने, अटैचमेंट के दूषित होने, या संदेशों को स्पैम के रूप में चिह्नित किए जाने का कारण बन सकती हैं।
पार्सिंग (प्राप्त करना):
- फोकस: एक रॉ ईमेल बाइट स्ट्रीम को उसके घटक भागों में अलग करना, विशिष्ट हेडर, बॉडी सामग्री और अटैचमेंट निकालना।
- प्राथमिक उपकरण:
email.parser.BytesParser
याemail.message_from_bytes()
, फिर परिणामीEmailMessage
ऑब्जेक्ट कोis_multipart()
,iter_parts()
,get_payload()
,get_filename()
, और हेडर एक्सेस जैसे तरीकों से नेविगेट करना। - मुख्य चुनौतियाँ: खराब प्रारूप वाले ईमेल को संभालना, कैरेक्टर एन्कोडिंग को सही ढंग से पहचानना (विशेषकर जब अस्पष्ट हो), लापता हेडर से निपटना, और विविध MIME संरचनाओं से मजबूती से डेटा निकालना।
`EmailMessage` का उपयोग करके आपके द्वारा बनाया गया एक संदेश `BytesParser` द्वारा पूरी तरह से पार्स करने योग्य होना चाहिए। इसी तरह, पार्सिंग के दौरान उत्पन्न MIME संरचना को समझना आपको यह जानकारी देता है कि आप स्वयं जटिल संदेश कैसे बना सकते हैं।
पाइथन के साथ वैश्विक ईमेल हैंडलिंग के लिए सर्वोत्तम प्रथाएँ
उन अनुप्रयोगों के लिए जो वैश्विक दर्शकों के साथ बातचीत करते हैं या विविध ईमेल स्रोतों को संभालते हैं, इन सर्वोत्तम प्रथाओं पर विचार करें:
- UTF-8 पर मानकीकरण करें: निर्माण करते समय और पार्सिंग के दौरान इसकी अपेक्षा करते समय, सभी टेक्स्ट सामग्री के लिए हमेशा UTF-8 का उपयोग करें। यह कैरेक्टर एन्कोडिंग के लिए वैश्विक मानक है और मोजिबेक (गड़बड़ टेक्स्ट) से बचाता है।
- ईमेल पते मान्य करें: भेजने से पहले, वितरण क्षमता सुनिश्चित करने के लिए प्राप्तकर्ता ईमेल पतों को मान्य करें। पार्सिंग के दौरान, `From`, `To`, या `Cc` हेडर में संभावित रूप से अमान्य या खराब प्रारूप वाले पतों के लिए तैयार रहें।
- कठोरता से परीक्षण करें: HTML और अटैचमेंट की सुसंगत प्रतिपादन सुनिश्चित करने के लिए विभिन्न ईमेल क्लाइंट्स (Gmail, Outlook, Apple Mail, Thunderbird) और प्लेटफार्मों के साथ अपने ईमेल निर्माण का परीक्षण करें। पार्सिंग के लिए, नमूना ईमेल की एक विस्तृत श्रृंखला के साथ परीक्षण करें, जिसमें असामान्य एन्कोडिंग, लापता हेडर, या जटिल नेस्टेड संरचनाएं शामिल हैं।
- पार्स किए गए इनपुट को साफ करें: आने वाले ईमेल से निकाले गए सामग्री को हमेशा अविश्वसनीय मानें। यदि आप इसे किसी वेब एप्लिकेशन में प्रदर्शित करते हैं तो XSS हमलों को रोकने के लिए HTML सामग्री को साफ करें। फ़ाइलों को सहेजते समय पथ ट्रैवर्सल या अन्य सुरक्षा कमजोरियों को रोकने के लिए अटैचमेंट फ़ाइल नामों और प्रकारों को मान्य करें।
- मजबूत त्रुटि हैंडलिंग: पेलोड डीकोड करते समय या संभावित रूप से लापता हेडर तक पहुँचते समय व्यापक
try-except
ब्लॉक लागू करें।UnicodeDecodeError
याKeyError
को शालीनता से संभालें। - बड़े अटैचमेंट संभालें: निर्माण करते समय (मेल सर्वर सीमाओं को पार करने से बचने के लिए) और पार्स करते समय (अत्यधिक मेमोरी उपयोग या डिस्क स्थान की खपत को रोकने के लिए) दोनों में अटैचमेंट के आकार के प्रति सचेत रहें। यदि आपका सिस्टम समर्थन करता है तो बड़े अटैचमेंट को स्ट्रीम करने पर विचार करें।
email.policy
का उपयोग करें: महत्वपूर्ण अनुप्रयोगों के लिए, ईमेल मानकों के साथ सख्त अनुपालन सुनिश्चित करने के लिए स्पष्ट रूप से एक `email.policy` (जैसे, `policy.SMTP`) चुनें, जो वितरण क्षमता और इंटरऑपरेबिलिटी को प्रभावित कर सकता है।- मेटाडेटा संरक्षण: पार्स करते समय, तय करें कि कौन सा मेटाडेटा (हेडर, मूल सीमा स्ट्रिंग्स) संरक्षित करना महत्वपूर्ण है, खासकर यदि आप एक मेल संग्रह या अग्रेषण प्रणाली बना रहे हैं।
निष्कर्ष
पाइथन का email
पैकेज किसी भी व्यक्ति के लिए एक अविश्वसनीय रूप से शक्तिशाली और लचीली लाइब्रेरी है जिसे प्रोग्रामेटिक रूप से ईमेल के साथ बातचीत करने की आवश्यकता है। MIME संदेशों के निर्माण और आने वाले ईमेल की मजबूत पार्सिंग दोनों में महारत हासिल करके, आप परिष्कृत ईमेल स्वचालन प्रणाली बनाने, ईमेल क्लाइंट बनाने, ईमेल डेटा का विश्लेषण करने और वस्तुतः किसी भी एप्लिकेशन में ईमेल कार्यात्मकताओं को एकीकृत करने की क्षमता को अनलॉक करते हैं।
यह पैकेज विचारपूर्वक MIME की अंतर्निहित जटिलताओं को संभालता है, जिससे डेवलपर्स को अपने ईमेल इंटरैक्शन की सामग्री और तर्क पर ध्यान केंद्रित करने की अनुमति मिलती है। चाहे आप वैश्विक दर्शकों को व्यक्तिगत न्यूज़लेटर भेज रहे हों या स्वचालित सिस्टम रिपोर्ट से महत्वपूर्ण डेटा निकाल रहे हों, email
पैकेज की गहरी समझ विश्वसनीय, इंटरऑपरेबल और विश्व स्तर पर जागरूक ईमेल समाधान बनाने में अमूल्य साबित होगी।